package com.angcyo.javafx.ui

import com.angcyo.javafx.BaseApp
import com.angcyo.library.ex.getResource
import javafx.fxml.FXMLLoader
import javafx.scene.Parent
import javafx.scene.Scene
import javafx.scene.image.Image
import javafx.stage.Modality
import javafx.stage.Stage
import javafx.stage.StageStyle
import javafx.stage.Window

/**
 * Email:angcyo@126.com
 * @author angcyo
 * @date 2021/01/06
 */

class DslStage {

    /**舞台的样式*/
    var stageStyle: StageStyle = StageStyle.DECORATED
    var modality = Modality.NONE

    /**舞台所属[Window], 用于决定是否是模态对话框
     * 还需要指定[modality]*/
    var owner: Window? = null
        set(value) {
            field = value
            if (value != null) {
                if (modality == Modality.NONE) {
                    modality = Modality.WINDOW_MODAL
                }
            }
        }
    var icons: List<Image>? = null

    /**舞台是否可以调整大小*/
    var resizable: Boolean = true
    var title: String? = null

    /**场景的参数*/
    var root: Parent? = null
    var sceneWidth = -1.0
    var sceneHeight = -1.0

    /**场景fxml资源名*/
    var rootFxml: String? = null

    /**初始化界面*/
    var initStage: (Stage, Parent) -> Unit = { _, _ -> }

    fun config(): Stage {
        val stage = Stage()
        stage.initStyle(stageStyle)
        stage.isResizable = resizable
        stage.title = title
        stage.initModality(modality)
        stage.initOwner(owner)

        if (icons == null) {
            BaseApp.getLogo()?.let {
                stage.icons.add(it)
            }
        } else {
            stage.icons.addAll(icons!!)
        }

        val rootNode: Parent? =
            root ?: if (rootFxml.isNullOrEmpty()) null else FXMLLoader.load<Parent>(getResource(rootFxml!!))

        stage.scene = Scene(rootNode, sceneWidth, sceneHeight)

        rootNode?.let {
            initStage(stage, it)
        }

        //前台显示
        stage.toFront()
        return stage
    }

    fun show(): Stage {
        return config().apply {
            show()
        }
    }

    fun showAndWait(): Stage {
        return config().apply {
            showAndWait()
        }
    }
}

fun dslStage(root: Parent, action: DslStage.() -> Unit = {}): Stage {
    val dslStage = DslStage()
    dslStage.root = root
    dslStage.action()
    return dslStage.show()
}

fun dslStage(rootFxml: String, action: DslStage.() -> Unit = {}): Stage {
    val dslStage = DslStage()
    dslStage.rootFxml = rootFxml
    dslStage.action()
    return dslStage.show()
}